#include "c_lua_interface.h"
#include "lua_util.h"

lua_State * g_pLuaState;

void Lua::SetLuaState( lua_State * luaState )
{

	g_pLuaState = luaState;

}

void Lua::CreateAttackThinkData( int entid, int moveid )
{
	
	lua_getglobal( g_pLuaState, "AttackThinkData" );
	
	if( LuaNil( g_pLuaState ) )
	{
		
		lua_pop( g_pLuaState, 1 );
		lua_newtable( g_pLuaState );
		lua_setglobal( g_pLuaState, "AttackThinkData" );
		lua_getglobal( g_pLuaState, "AttackThinkData" );
		
	}
	
	char s[15];
	
	sprintf( s, "TD%d_%d", entid, moveid );

	lua_getfield( g_pLuaState, -1, s );

	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_pushnil( g_pLuaState );

		lua_setfield( g_pLuaState, -2, s );
		
	}
	
	lua_pop( g_pLuaState, 1 );

	lua_newtable( g_pLuaState );
	lua_setfield( g_pLuaState, -2, s );
	
	lua_pop( g_pLuaState, 1 );

	
}

bool Lua::AttackThinkFunc( int funcid, int attacker, int victim, int moveid )
{

	lua_rawgeti( g_pLuaState, LUA_REGISTRYINDEX, funcid );

	lua_newtable( g_pLuaState );
	lua_pushnumber( g_pLuaState, attacker );
	lua_setfield( g_pLuaState, -2, "id" );
	
	lua_newtable( g_pLuaState );
	lua_getglobal( g_pLuaState, "Entity" );
	lua_setfield( g_pLuaState, -2, "__index" );
	lua_setmetatable( g_pLuaState, -2 );
	
	lua_newtable( g_pLuaState );
	lua_pushnumber( g_pLuaState, victim );
	lua_setfield( g_pLuaState, -2, "id" );
	
	lua_newtable( g_pLuaState );
	lua_getglobal( g_pLuaState, "Entity" );
	lua_setfield( g_pLuaState, -2, "__index" );
	lua_setmetatable( g_pLuaState, -2 );

	char s[15];
	
	sprintf( s, "TD%d_%d", attacker, moveid );
	lua_pushstring( g_pLuaState, s );
	
	if( lua_pcall( g_pLuaState, 3, 1, 0 ) > 0 )
	{
		
		Log::Debug( lua_tostring( g_pLuaState, -1 ) );
		lua_pop( g_pLuaState, 1 );
		
	} else
	{
		
		bool ret = lua_toboolean( g_pLuaState, -1 );

		return ret;
		
	}
	
	return false;
	
}

void Lua::TimedUIMessage( std::string text, double x, double y, int width, int time )
{
	
	DelayedTimedUIMessage( text, x, y, width, time, 0 );
	
}

void Lua::DelayedTimedUIMessage( std::string text, double x, double y, int width, int time, int delay )
{
	
	
	lua_getglobal( g_pLuaState, "LuaC" );
	
	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_getfield( g_pLuaState, -1, "TimedUIMessage" );
	
		if( !LuaNil( g_pLuaState ) )
		{
			
			lua_pushstring( g_pLuaState, text.c_str() );
			lua_pushnumber( g_pLuaState, x );
			lua_pushnumber( g_pLuaState, y );
			lua_pushnumber( g_pLuaState, width );
			lua_pushnumber( g_pLuaState, time );
			lua_pushnumber( g_pLuaState, delay );
			
			if( lua_pcall( g_pLuaState, 6, 0, 0 ) > 0 )
			{
				
				Log::Debug( lua_tostring( g_pLuaState, -1 ) );
				lua_pop( g_pLuaState, 1 );
				
			}
			
		} else
			lua_pop( g_pLuaState, 1 );
		
	}
	
	lua_pop( g_pLuaState, 1 );
	
}

void Lua::GenerateBattleTable()
{
	
	lua_getglobal( g_pLuaState, "BattleEnts" );
	
	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_pushnil( g_pLuaState );
		lua_setglobal( g_pLuaState, "BattleEnts" );
		
	}
	
	lua_pop( g_pLuaState, 1 );
	
	lua_newtable( g_pLuaState );
	lua_setglobal( g_pLuaState, "BattleEnts" );
	
}

void Lua::CallFunction( int func )
{
	
	lua_rawgeti( g_pLuaState, LUA_REGISTRYINDEX, func );
	
	if( !LuaNil( g_pLuaState ) )
	{
		
			
		if( lua_pcall( g_pLuaState, 0, 0, 0 ) > 0 )
		{
				
			Log::Debug( lua_tostring( g_pLuaState, -1 ) );
			lua_pop( g_pLuaState, 1 );
				
		} 		
		
	} else
		lua_pop( g_pLuaState, 1 );
	
}

void Lua::EntityOnTouch( int ent, int ent2 )
{
	
	lua_getglobal( g_pLuaState, "EntCallBacks" );
	lua_pushnumber( g_pLuaState, ent );
	lua_gettable( g_pLuaState, -2 );
	
	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_getfield( g_pLuaState, -1, "OnTouch" );	

		if( !LuaNil( g_pLuaState ) )
		{
			
			lua_pushnumber( g_pLuaState, ent );
			lua_pushnumber( g_pLuaState, ent2 );
			
			if( lua_pcall( g_pLuaState, 2, 0, 0 ) > 0 )
			{
				
				Log::Debug( lua_tostring( g_pLuaState, -1 ) );
				lua_pop( g_pLuaState, 1 );
				
			} 
			
			lua_pop( g_pLuaState, 2 );
			
		} else
			lua_pop( g_pLuaState, 3 );
		
	} else
		lua_pop( g_pLuaState, 2 );
	
}


void Lua::SetGlobalBool( std::string name, bool value )
{
	
	lua_getglobal( g_pLuaState, "G" );
	
	lua_pushboolean( g_pLuaState, value );
	lua_setfield( g_pLuaState, -2, name.c_str() );
	
}


void Lua::SetGlobalInt( std::string name, int value )
{
	
	lua_getglobal( g_pLuaState, "G" );
	
	lua_pushnumber( g_pLuaState, value );
	lua_setfield( g_pLuaState, -2, name.c_str() );
	
}

void Lua::AddEntityToBattleTable( int type, int entid, int data )
{
	
	lua_newtable( g_pLuaState );
	lua_pushnumber( g_pLuaState, entid );
	lua_setfield( g_pLuaState, -2, "id" );
	
	lua_pushboolean( g_pLuaState, ( type == 1 ) );
	lua_setfield( g_pLuaState, -2, "isEnemy" );
	
	if( data > -1 )
	{
		
		lua_newtable( g_pLuaState );
		
		lua_newtable( g_pLuaState );
		lua_rawgeti( g_pLuaState, LUA_REGISTRYINDEX, data );
		lua_setfield( g_pLuaState, -2, "__index" );
		
		lua_setmetatable( g_pLuaState, -2 );
		
		lua_setfield( g_pLuaState, -2, "Data" );
	
	}
		
	lua_newtable( g_pLuaState );
	lua_getglobal( g_pLuaState, "Entity" );
	lua_setfield( g_pLuaState, -2, "__index" );
	lua_setmetatable( g_pLuaState, -2 );
	
	lua_getglobal( g_pLuaState, "BattleEnts" );
	lua_insert( g_pLuaState, -2 );
	
	int c = lua_rawlen( g_pLuaState, -2 ) + 1;

	lua_pushnumber( g_pLuaState, c );
	lua_insert( g_pLuaState, -2 );
	
	lua_settable( g_pLuaState, -3 );
	
	lua_pop( g_pLuaState, 1 );
	
}

void Lua::BattleText( std::string text, int time, int speed )
{
	
	lua_getglobal( g_pLuaState, "LuaC" );
	
	
	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_getfield( g_pLuaState, -1, "BattleText" );
	
		if( !LuaNil( g_pLuaState ) )
		{
			
			lua_pushstring( g_pLuaState, text.c_str() );
			lua_pushnumber( g_pLuaState, time );
			lua_pushnumber( g_pLuaState, speed );
			
			if( lua_pcall( g_pLuaState, 3, 0, 0 ) > 0 )
			{
				
				Log::Debug( lua_tostring( g_pLuaState, -1 ) );
				lua_pop( g_pLuaState, 1 );
				
			}
			
		} else
			lua_pop( g_pLuaState, 1 );
		
	}
	
	lua_pop( g_pLuaState, 1 );	
	
}

void Lua::PopupText( std::string text, double x, double y, int speed, int fadeout )
{
	
	lua_getglobal( g_pLuaState, "LuaC" );
	
	if( !LuaNil( g_pLuaState ) )
	{
		
		lua_getfield( g_pLuaState, -1, "PopupText" );
	
		if( !LuaNil( g_pLuaState ) )
		{
			
			lua_pushstring( g_pLuaState, text.c_str() );
			lua_pushnumber( g_pLuaState, x );
			lua_pushnumber( g_pLuaState, y );
			lua_pushnumber( g_pLuaState, speed );
			lua_pushnumber( g_pLuaState, fadeout );
			
			if( lua_pcall( g_pLuaState, 5, 0, 0 ) > 0 )
			{
				
				Log::Debug( lua_tostring( g_pLuaState, -1 ) );
				lua_pop( g_pLuaState, 1 );
				
			}
			
		} else
			lua_pop( g_pLuaState, 1 );
		
	}
	
	lua_pop( g_pLuaState, 1 );
	
	
}

bool Lua::GetEntityLuaTableValue_Bool( int id, std::string key )
{
	
	LuaGetEntityTable( g_pLuaState, id );
	
	lua_getfield( g_pLuaState, -1, key.c_str() );
	
	bool ret = lua_toboolean( g_pLuaState, -1 );
	
	lua_pop( g_pLuaState, 3 );
	
	return ret;
	
}

void Lua::SetEntityLuaTableValue_Bool( int id, std::string key, bool value )
{
	
	LuaGetEntityTable( g_pLuaState, id );
	
	lua_pushboolean( g_pLuaState, value );
	lua_setfield( g_pLuaState, -2, key.c_str() );
	
	lua_pop( g_pLuaState, 2 );
	
}


void Lua::SetEntityLuaTableValue_Int( int id, std::string key, int value )
{
	
	LuaGetEntityTable( g_pLuaState, id );
	
	lua_pushnumber( g_pLuaState, value );
	lua_setfield( g_pLuaState, -2, key.c_str() );
	
	lua_pop( g_pLuaState, 2 );
	
}
